#include "head.h"

// 单链表的创建
U_list *S_List_init()
{
    // 创建头节点
    U_list *list = (U_list *)malloc(sizeof(U_list));
    // 判断是否创建成功
    if (list != NULL)
    {
        // 如果成功则初始化链表中的头节点为 NULL
        list->next = NULL;
    }
    else
    {
        printf("创建失败\n");
        return NULL;
    }
    // 返回链表结构体
    return list;
}

// 单链表的插入
void S_List_insert(U_list *list, U_data data, int pos)
{
    if (list == NULL)
    {
        printf("链表为NULL\n");
        return;
    }

    U_node *new_node = (U_node *)malloc(sizeof(U_node));
    if (new_node == NULL)
    {
        printf("new_node创建失败\n");
        return;
    }
    new_node->next = NULL;
    new_node->data = data;

    if (pos == 1)
    {
        new_node->next = list->next;
        list->next = new_node;
        return;
    }

    U_node *ptr = list->next;

    for (size_t i = 1; i < pos - 1 && ptr != NULL; i++)
    {
        ptr = ptr->next;
    }

    if (ptr == NULL)
    {
        printf("ptr已经指向NULL\n");
        free(new_node);
        return;
    }
    new_node->next = ptr->next;
    ptr->next = new_node;

    return;
}

// 单链表的删除
void S_List_delete(U_list *list, int pos)
{
    if (list == NULL)
    {
        printf("链表为NULL\n");
        return;
    }
    if (list->next == NULL)
    {
        printf("链表无数据\n");
        return;
    }

    U_node *ptr_1 = list->next;
    U_node *ptr_2 = NULL;
    if (pos == 1)
    {
        list->next = ptr_1->next;
        free(ptr_1);
        return;
    }

    for (size_t i = 0; i < pos - 1 && ptr_1->next != NULL; i++)
    {
        ptr_2 = ptr_1;
        ptr_1 = ptr_1->next;
    }
    if (ptr_1 == NULL)
    {
        printf("ptr_1指向null\n");
        return;
    }
    ptr_2->next = ptr_1->next;

    free(ptr_1);
    return;
}

// 单链表的查找返回指针
U_node *S_List_find_name(U_list *list, char *name)
{
    if (list == NULL)
    {
        printf("链表为NULL\n");
        return NULL;
    }

    U_node *ptr = list->next;
    while (ptr != NULL)
    {
        if (strcmp(ptr->data.name, name) == 0)
        {
            return ptr;
        }
        ptr = ptr->next;
    }

    return NULL;
}
// 查找返回位置
int S_List_find_name_num(U_list *list, char *name)
{
    if (list == NULL)
    {
        printf("链表为NULL\n");
        return 0;
    }

    U_node *ptr = list->next;
    for (int i = 1; ptr != NULL; i++)
    {
        if (strcmp(ptr->data.name, name) == 0)
        {
            return i;
        }
        ptr = ptr->next;
    }

    return 0;
}
// 单链表的遍历
void S_List_print(U_list *list)
{
    if (list == NULL)
    {
        printf("链表为NULL\n");
        return;
    }
    if (list->next == NULL)
    {
        printf("链表无数据\n");
        return;
    }
    U_node *ptr = list->next;
    while (ptr != NULL)
    {
        printf("用户名:%s\t密码:%s\t身份码:%d\t余额:%d\t票数%d\n",
               ptr->data.name, ptr->data.passwd, ptr->data.grade, ptr->data.value, ptr->data.ticket_num);
        ptr = ptr->next;
    }
    return;
}

// 单链表的清空
void S_List_clear(U_list *list)
{
    if (list == NULL)
    {
        printf("链表为NULL\n");
        return;
    }
    if (list->next == NULL)
    {
        // printf("\n");
        return;
    }

    U_node *ptr_1 = list->next;
    U_node *ptr_2 = ptr_1->next;

    while (ptr_1 != NULL)
    {
        free(ptr_1);
        ptr_1 = ptr_2;
        if (ptr_2 != NULL)
        {
            ptr_2 = ptr_2->next;
        }
    }
    list->next = NULL;
}

// 单链表的合并
U_list *S_List_merge(U_list *list1, U_list *list2)
{
    if (list1 == NULL || list2 == NULL)
    {
        printf("链表不存在\n");
        return list1;
    }

    // 1、求链表list1 的链表长度
    U_node *ptr_1 = list1->next;
    int len = 0;

    while (ptr_1 != NULL)
    {
        ptr_1 = ptr_1->next;
        len++;
    }
    // 插入到链表中
    ptr_1 = list1->next;
    U_node *ptr_2 = list2->next;
    while (ptr_2 != NULL)
    {
        len++;
        S_List_insert(list1, ptr_2->data, len);
        ptr_2 = ptr_2->next;
    }

    return list1;
}

// 单链表的销毁
void S_List_free(U_list **list)
{
    if (list == NULL || *list == NULL)
    {
        printf("链表为NULL\n");
        return;
    }

    U_node *ptr_1 = (*list)->next;
    U_node *ptr_2 = ptr_1->next;

    while (ptr_1 != NULL)
    {
        free(ptr_1);
        ptr_1 = ptr_2;
        if (ptr_2 != NULL)
        {
            ptr_2 = ptr_2->next;
        }
    }

    free(*list);
    *list = NULL;
}

// 向文件写入用户信息
void S_List_File_print(U_list *list, const char *file_name)
{
    // 安全判断
    if (list == NULL)
    {
        printf("链表为NULL\n");
        return;
    }
    if (list->next == NULL)
    {
        printf("链表无数据\n");
        return;
    }

    FILE *fp = fopen(file_name, "w+");
    if (fp == NULL)
    {
        printf("文件创建失败\n");
        return;
    }
    fseek(fp, 0, SEEK_SET);

    U_node *ptr = list->next;

    while (ptr != NULL)
    {
        fprintf(fp, "用户名:%s\t密码:%s\t身份码:%d\t余额:%d\t票数:%d\n",
                ptr->data.name, ptr->data.passwd, ptr->data.grade, ptr->data.value, ptr->data.ticket_num);
        ptr = ptr->next;
    }

    fflush(fp); // 刷新文件

    fclose(fp);
}

// 从文件读取用户信息
void S_List_File_scanf(U_list *list, const char *file_name)
{
    // 安全判断
    if (list == NULL)
    {
        printf("链表为NULL\n");
        return;
    }

    FILE *fp = fopen(file_name, "r");
    if (fp == NULL)
    {
        printf("文件打开失败\n");
        return;
    }
    // 移动光标
    fseek(fp, 0, SEEK_SET);
    // 清空链表
    S_List_clear(list);

    U_data data;
    char ch = 0;
    int pos = 0;

    // 检测文件行数
    while ((ch = fgetc(fp)) != EOF)
    {
        if (ch == '\n')
        {
            pos++;
        }
    }

    // 移动光标
    fseek(fp, 0, SEEK_SET);

    for (size_t i = 0; i < pos; i++)
    {
        // "用户名:%s\t密码:%s\t身份码:%d\t余额:%d\n"
        fscanf(fp, "用户名:%s\t密码:%s\t身份码:%d\t余额:%d\t票数:%d\n",
               data.name, data.passwd, &data.grade, &data.value, &data.ticket_num);
        S_List_insert(list, data, i + 1);
    }

    fflush(fp); // 刷新文件

    fclose(fp);
}

//===============================================管理员修改普通用户====================================
void change_user_information()
{
    // FlightSystem Sys_init(void);
    //     FlightSystem Flight_sys;

    U_list *p1 = S_List_init();
    U_list *p2 = S_List_init();
    U_list *p3 = S_List_init();
    U_list *p4 = S_List_init();
    U_list *p5 = S_List_init();
    S_List_File_scanf(p1, REGULAR_FILE);  // 普通用户信息文件
    S_List_File_scanf(p2, SILVER_FILE);   // 银卡会员信息文件 (9折)
    S_List_File_scanf(p3, GOLD_FILE);     // 金卡会员信息文件 (8折)
    S_List_File_scanf(p4, PLATINUM_FILE); // 白金会员信息文件 (7折)
    S_List_File_scanf(p5, ADMIN_FILE);    // 管理员信息文件

    //    // 用户信息合表
    U_list *list = S_List_init();
    // list = S_List_merge(list,p1);    // 管理员账户信息文件
    list = S_List_merge(list, p1); // 普通用户信息文件
    list = S_List_merge(list, p2); // 银卡会员信息文件 (9折)
    list = S_List_merge(list, p3); // 金卡会员信息文件 (8折)
    list = S_List_merge(list, p4); // 白金会员信息文件 (7折)
    char a[20];
    int b = 0;
    S_List_print(list);
    printf("请输入你要修改的用户名:\n");
    scanf("%s", a);
    U_node *pt = S_List_find_name(list, a);

    // printf("%d",b);
    printf("用户名:%s\t密码:%s\t身份码:%d\t余额:%d\t票数:%d\n", pt->data.name, pt->data.passwd, pt->data.grade, pt->data.value, pt->data.ticket_num);
    if (pt->data.grade == 2)
    {
        b = S_List_find_name_num(p1, a);
        S_List_delete(p1, b);
    }
    if (pt->data.grade == 3)
    {
        b = S_List_find_name_num(p2, a);
        S_List_delete(p2, b);
    }
    if (pt->data.grade == 4)
    {
        b = S_List_find_name_num(p3, a);
        S_List_delete(p3, b);
    }
    if (pt->data.grade == 5)
    {
        b = S_List_find_name_num(p4, a);
        S_List_delete(p4, b);
    }
    printf("用户名:\n");
    scanf("%s", pt->data.name);
    printf("密码:\n");
    scanf("%s", pt->data.passwd);
    printf("身份码:\n");
    scanf("%d", &pt->data.grade);
    printf("余额:\n");
    scanf("%d", &pt->data.value);
    printf("票数:\n");
    scanf("%d", &pt->data.ticket_num);
    switch (pt->data.grade)
    {
    case (1):
        S_List_insert(p5, pt->data, 1);
        break;
    case (2):
        S_List_insert(p1, pt->data, 1);
        break;
    case (3):
        S_List_insert(p2, pt->data, 1);
        break;
    case (4):
        S_List_insert(p3, pt->data, 1);
        break;
    case (5):
        S_List_insert(p4, pt->data, 1);
        break;
    default:
        break;
    }
    S_List_File_print(p1, REGULAR_FILE);
    S_List_File_print(p2, SILVER_FILE);
    S_List_File_print(p3, GOLD_FILE);
    S_List_File_print(p4, PLATINUM_FILE);
    S_List_File_print(p5, ADMIN_FILE);
    sleep(3);
    system("clear");
    return admain();
}
//=======================================用户修改密码======================================================
void change_password(U_data data)
{
    U_list *p1 = S_List_init();
    U_list *p2 = S_List_init();
    U_list *p3 = S_List_init();
    U_list *p4 = S_List_init();
    U_list *p5 = S_List_init();
    S_List_File_scanf(p1, REGULAR_FILE);  // 普通用户信息文件
    S_List_File_scanf(p2, SILVER_FILE);   // 银卡会员信息文件 (9折)
    S_List_File_scanf(p3, GOLD_FILE);     // 金卡会员信息文件 (8折)
    S_List_File_scanf(p4, PLATINUM_FILE); // 白金会员信息文件 (7折)
    S_List_File_scanf(p5, ADMIN_FILE);    // 管理员信息文件

    //    // 用户信息合表
    U_list *list = S_List_init();
    // list = S_List_merge(list,p1);    // 管理员账户信息文件
    list = S_List_merge(list, p1); // 普通用户信息文件
    list = S_List_merge(list, p2); // 银卡会员信息文件 (9折)
    list = S_List_merge(list, p3); // 金卡会员信息文件 (8折)
    list = S_List_merge(list, p4); // 白金会员信息文件 (7折)
    char a[10];
    //    U_list*head_list=S_List_init();
    //  U_node*pt=head_list->next;
    // printf("1");
    U_node *pt = S_List_find_name(list, data.name);
    U_node *pr;
    switch (pt->data.grade)
    {
    case (2): // 普通用户改密码
        pr = S_List_find_name(p1, data.name);
        printf("请输入修改密码:");
        scanf("%s", a);
        strcpy(pr->data.passwd, a);
        S_List_File_print(p1, REGULAR_FILE);
        break;

    case (3): // 修改白银用户
        pr = S_List_find_name(p2, data.name);
        printf("请输入修改密码:");
        scanf("%s", a);
        strcpy(pr->data.passwd, a);
        S_List_File_print(p2, SILVER_FILE);
        break;

    case (4): // 修改黄金用户
        pr = S_List_find_name(p3, data.name);
        printf("请输入修改密码:");
        scanf("%s", a);
        strcpy(pr->data.passwd, a);
        S_List_File_print(p3, GOLD_FILE);
        break;

    case (5): // 修改白金用户
        pr = S_List_find_name(p4, data.name);
        printf("请输入修改密码:");
        scanf("%s", a);
        strcpy(pr->data.passwd, a);
        S_List_File_print(p4, PLATINUM_FILE);
        break;
    }
    F_list *p = D_List_init();
    D_List_file_scanf(p);

    sleep(3);
    system("clear");
    return user(p, data);
}
//========================================================用户充值================================================
void user_pay(U_data data)
{
    U_list *p1 = S_List_init();
    U_list *p2 = S_List_init();
    U_list *p3 = S_List_init();
    U_list *p4 = S_List_init();
    U_list *p5 = S_List_init();
    S_List_File_scanf(p1, REGULAR_FILE);  // 普通用户信息文件
    S_List_File_scanf(p2, SILVER_FILE);   // 银卡会员信息文件 (9折)
    S_List_File_scanf(p3, GOLD_FILE);     // 金卡会员信息文件 (8折)
    S_List_File_scanf(p4, PLATINUM_FILE); // 白金会员信息文件 (7折)
    S_List_File_scanf(p5, ADMIN_FILE);    // 管理员信息文件
    int a;
    //    // 用户信息合表
    U_list *list = S_List_init();
    // list = S_List_merge(list,p1);    // 管理员账户信息文件
    list = S_List_merge(list, p1); // 普通用户信息文件
    list = S_List_merge(list, p2); // 银卡会员信息文件 (9折)
    list = S_List_merge(list, p3); // 金卡会员信息文件 (8折)
    list = S_List_merge(list, p4); // 白金会员信息文件 (7折)
    U_node *pt = S_List_find_name(list, data.name);
    U_node *pr;
    int b;
    switch (pt->data.grade)
    {

    case (2): // 普通用户充值
        b = S_List_find_name_num(p1, data.name);
        pr = S_List_find_name(p1, data.name);
        printf("请输入充值金额:");
        scanf("%d", &a);
        pr->data.value = pr->data.value + a;
        if (pr->data.value <= 2000 && pr->data.value > 1000) // 判断充值后属于白银用户
        {
            pr->data.grade = 3;                  // 修改身份码
            S_List_insert(p2, pr->data, 1);      // 插入白银用户
            S_List_File_print(p2, SILVER_FILE);  // 写入插入对象后的文件
            S_List_delete(p1, b);                // 删除普通用户的充值对象
            S_List_File_print(p1, REGULAR_FILE); // 写入删除对象后的文件
        }
        if (pr->data.value <= 3000 && pr->data.value > 2000) // 判断充值后属于黄金用户
        {
            pr->data.grade = 4;
            S_List_insert(p3, pr->data, 1);      // 插入黄金用户
            S_List_File_print(p3, GOLD_FILE);    // 写入插入对象后的文件
            S_List_delete(p1, b);                // 删除普通用户的充值对象
            S_List_File_print(p1, REGULAR_FILE); // 写入删除对象后的文件
        }
        if (pr->data.value > 3000) // 判断充值后属于白金用户
        {
            pr->data.grade = 5;
            S_List_insert(p4, pr->data, 1);       // 插入白金用户
            S_List_File_print(p4, PLATINUM_FILE); // 写入插入对象后的文件
            S_List_delete(p1, b);                 // 删除普通用户的充值对象
            S_List_File_print(p1, REGULAR_FILE);  // 写入删除对象后的文件
        }
        S_List_File_print(p1, REGULAR_FILE);
        break;

    case (3): // 白银用户充值
        b = S_List_find_name_num(p2, data.name);
        pr = S_List_find_name(p2, data.name);
        printf("请输入充值金额:");
        scanf("%d", &a);
        pr->data.value = pr->data.value + a;
        if (pr->data.value <= 3000 && pr->data.value > 2000) // 判断充值后属于黄金用户
        {
            pr->data.grade = 4;
            S_List_insert(p3, pr->data, 1);     // 插入黄金用户
            S_List_File_print(p3, GOLD_FILE);   // 写入插入对象后的文件
            S_List_delete(p2, b);               // 删除白银用户的充值对象
            S_List_File_print(p2, SILVER_FILE); // 写入删除对象后的文件
        }
        if (pr->data.value > 3000) // 判断充值后属于白金用户
        {
            pr->data.grade = 5;
            S_List_insert(p4, pr->data, 1);       // 插入白金用户
            S_List_File_print(p4, PLATINUM_FILE); // 写入插入对象后的文件
            S_List_delete(p2, b);                 // 删除白银用户的充值对象
            S_List_File_print(p2, SILVER_FILE);   // 写入删除对象后的文件
        }
        S_List_File_print(p2, SILVER_FILE);
        break;

    case (4): // 黄金用户充值
        b = S_List_find_name_num(p3, data.name);
        pr = S_List_find_name(p3, data.name);
        printf("请输入充值金额:");
        scanf("%d", &a);
        pr->data.value = pr->data.value + a;
        if (pr->data.value > 3000) // 判断充值后属于白金用户
        {
            pr->data.grade = 5;
            S_List_insert(p4, pr->data, 1);       // 插入白金用户
            S_List_File_print(p4, PLATINUM_FILE); // 写入插入对象后的文件
            S_List_delete(p3, b);                 // 删除黄金用户的充值对象
            S_List_File_print(p3, GOLD_FILE);     // 写入删除对象后的文件
        }
        S_List_File_print(p3, GOLD_FILE);
        break;

    case (5): // 白金用户充值
        b = S_List_find_name_num(p4, data.name);
        pr = S_List_find_name(p4, data.name);
        printf("请输入充值金额:");
        scanf("%d", &a);
        pr->data.value = pr->data.value + a;
        S_List_File_print(p4, PLATINUM_FILE); // 写入插入对象后的文件
        break;

    default:
        printf("充值错误。");
        break;
    }

    F_list *p = D_List_init();
    D_List_file_scanf(p);

    sleep(3);
    system("clear");
    return user(p, data);
}
//=========================================用户查看航班================
void look_user(U_data data)
{
    printf("班次    机型        起点站  终点站  起飞时间    到达时间    飞行时间    票价  载客量  剩余座位  是否飞\n");
    printf("--------------------------------------------------------------------------------------------------\n");
    F_list *p = D_List_init();
    D_List_file_scanf(p);
    D_List_print(p);
    // F_list *p = D_List_init();
    // D_List_file_scanf(p);

    sleep(3);
    system("clear");
    return user(p, data);
}
